/*
# 文件名称：main.go
#
# 文件描述：
#
# 创建日期：2020/11/24 10:15
#
# 文件版本：1.0
#
# 作    者：zzq
#
# (C) Copyright 2016-2020, Jeeseen Technologies. All Rights Reserved
#
# 修改历史：
#
*/
package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"regexp"
	"strconv"
	"strings"
)

/*
1、将大文件切分多个小文件（指定大小）
2、将小文件还原成大文件

后期加密

分割
输入文件路径 分割大小(单位： M)
以文件名称生成目录（XXX_CC）
遍历读取文件生成小文件 （1.cc）

拼接
读取目录下的问（XXX.cc）
生成一个以目录名称文件（XXX）
文件名称排序升序 遍历读取文件内容写到(XXX)

*/



func CCFile(fileName string, size int) {
	readSize := int64(size * 1024 * 1024)
	fileInfo, err := os.Open(fileName)
	defer fileInfo.Close()
	if err != nil {
		if os.IsNotExist(err) {
			fmt.Println("File does not exist.")
			return
		}
		fmt.Println("Open File Error.", err)
		return
	}

	fName := fileInfo.Name()
	FInfo, _ := fileInfo.Stat()
	fSize := FInfo.Size()
	if readSize > fSize{
		readSize = fSize
	}

	dirName := fmt.Sprintf("%v_CC", fName)
	err = os.Mkdir(dirName, 777)
	if err != nil {
		fmt.Println("Mkdir Error Failed dirName.", dirName)
		fmt.Println(err)
		return
	}
	var num int64 = 1
	for {

		ifbrack := false
		rSize := num * readSize
		if rSize >= fSize{
			readSize = fSize - ((num-1) * readSize)
			ifbrack = true
		}
		fmt.Println(num)
		fmt.Println(readSize)
		fmt.Println(fSize)
		fmt.Println(rSize)
		buf := make([]byte, readSize)
		fileInfo.Read(buf)
		newFileName := fmt.Sprintf("%v/%v.cc", dirName,num)
		f, err := os.Create(newFileName)
		defer f.Close()
		if err != nil {
			if err == io.EOF{
				return
			}
			fmt.Println("create new file error.", err)
			return
		}

		f.Write(buf)
		if ifbrack{
			return
		}

		num = num + 1
	}

}

func UnCCFile(dirName string){
	files, _ := ioutil.ReadDir(dirName)
	fName := strings.Split(dirName, "_")[0]
	fName = fmt.Sprintf("%v", fName)
	dst, err := os.Create(fName)
	defer dst.Close()
	if err  != nil{
		fmt.Println(err)
		return
	}

	for _, value := range files{
		fileName := value.Name()
		if strings.HasSuffix(fileName, ".cc"){
			fmt.Println(fileName)
			fr, err := os.Open(fmt.Sprintf("%v/%v", dirName, fileName))
			defer fr.Close()
			if err != nil {
				fmt.Println(err)
				return
			}
			var readSize int64 = 10 * 1024 * 1024
			fStat, _ := fr.Stat()
			fSize := fStat.Size()
			if fSize < readSize{
				readSize = fSize
			}

			for {
				buf := make([]byte, readSize)
				n, err := fr.Read(buf)

				fmt.Println(n)
				if err != io.EOF && err != nil{

					fmt.Println(err)
					break
				}
				if n == 0{
					break
				}
				dst.Write(buf)
			}

		}

	}
}

func main()  {
	////CCFile("test.zip", 10)
	//UnCCFile("test.zip_CC")
	args := os.Args
	fmt.Println(args)
	if len(args) < 3{
		fmt.Println("CC -c <文件名称> <分割后文件大小 单位：M> 或者 CC -u <目录>")
		return
	}
	option := args[1]
	if option == "-c"{
		size := 10
		if len(args) >= 4{
			sizeStr := args[3]
			if sizeStr != "" {
				pattern := "\\d+" //反斜杠要转义
				result,_ := regexp.MatchString(pattern,sizeStr)
				if result == false{
					fmt.Println("必须是整数。", sizeStr)
					return
				}
				size, _ = strconv.Atoi(sizeStr)
			}
		}
		CCFile(args[2], size)
	}else if option == "-u"{
		UnCCFile(args[2])
	}else {
		fmt.Println("CC -c <文件名称> <分割后文件大小 单位：M> 或者 CC -u <目录>")
		return
	}
}